package com.haoxuer.discover.user.rest.resource;

import com.haoxuer.discover.rest.base.ResponseObject;
import com.haoxuer.discover.user.api.apis.UserInfoApi;
import com.haoxuer.discover.user.api.domain.list.MenuList;
import com.haoxuer.discover.user.api.domain.list.UserInfoList;
import com.haoxuer.discover.user.api.domain.page.UserInfoPage;
import com.haoxuer.discover.user.api.domain.request.*;
import com.haoxuer.discover.user.api.domain.response.UserInfoResponse;
import com.haoxuer.discover.user.api.domain.simple.MenuSimple;
import com.haoxuer.discover.user.data.dao.MenuDao;
import com.haoxuer.discover.user.data.dao.UserInfoDao;
import com.haoxuer.discover.user.data.entity.Menu;
import com.haoxuer.discover.user.data.entity.UserInfo;
import com.haoxuer.discover.user.data.entity.UserRole;
import com.haoxuer.discover.user.data.enums.SecurityType;
import com.haoxuer.discover.user.data.request.ResetPasswordRequest;
import com.haoxuer.discover.user.data.request.UpdatePasswordRequest;
import com.haoxuer.discover.user.rest.convert.MenuSimpleConvert;
import com.haoxuer.discover.user.rest.convert.UserInfoResponseConvert;
import com.haoxuer.discover.user.rest.convert.UserInfoSimpleConvert;
import com.haoxuer.discover.config.utils.ConverResourceUtils;
import com.haoxuer.discover.data.page.Filter;
import com.haoxuer.discover.data.page.Order;
import com.haoxuer.discover.data.page.Page;
import com.haoxuer.discover.data.page.Pageable;
import com.haoxuer.discover.data.utils.FilterUtils;
import com.haoxuer.discover.user.shiro.realm.ShiroUser;
import com.haoxuer.discover.user.shiro.utils.UserUtil;
import jodd.util.StringUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.haoxuer.discover.user.rest.conver.PageableConver;
import com.haoxuer.discover.data.utils.BeanDataUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Transactional
@Component
public class UserInfoResource implements UserInfoApi {

    @Autowired
    private UserInfoDao dataDao;

    @Autowired
    private MenuDao menuDao;


    @Override
    public UserInfoResponse create(UserInfoDataRequest request) {
        UserInfoResponse result = new UserInfoResponse();

        UserInfo bean = new UserInfo();
        handleData(request, bean);
        dataDao.save(bean);
        result = new UserInfoResponseConvert().conver(bean);
        return result;
    }

    @Override
    public UserInfoResponse update(UserInfoDataRequest request) {
        UserInfoResponse result = new UserInfoResponse();
        if (request.getId() == null) {
            result.setCode(501);
            result.setMsg("无效id");
            return result;
        }
        UserInfo bean = dataDao.findById(request.getId());
        if (bean == null) {
            result.setCode(502);
            result.setMsg("无效id");
            return result;
        }
        handleData(request, bean);
        result = new UserInfoResponseConvert().conver(bean);
        return result;
    }

    private void handleData(UserInfoDataRequest request, UserInfo bean) {
        BeanDataUtils.copyProperties(request, bean);

    }

    @Override
    public UserInfoResponse delete(UserInfoDataRequest request) {
        UserInfoResponse result = new UserInfoResponse();
        if (request.getId() == null) {
            result.setCode(501);
            result.setMsg("无效id");
            return result;
        }
        dataDao.deleteById(request.getId());
        return result;
    }

    @Override
    public UserInfoResponse view(UserInfoDataRequest request) {
        UserInfoResponse result = new UserInfoResponse();
        UserInfo bean = dataDao.findById(request.getId());
        if (bean == null) {
            result.setCode(1000);
            result.setMsg("无效id");
            return result;
        }
        result = new UserInfoResponseConvert().conver(bean);
        return result;
    }

    @Override
    public UserInfoList list(UserInfoSearchRequest request) {
        UserInfoList result = new UserInfoList();

        List<Filter> filters = new ArrayList<>();
        filters.addAll(FilterUtils.getFilters(request));
        List<Order> orders = new ArrayList<>();
        if ("asc".equals(request.getSortMethod())) {
            orders.add(Order.asc("" + request.getSortField()));
        } else if ("desc".equals(request.getSortMethod())) {
            orders.add(Order.desc("" + request.getSortField()));
        } else {
            orders.add(Order.desc("id"));
        }
        List<UserInfo> organizations = dataDao.list(0, request.getSize(), filters, orders);
        UserInfoSimpleConvert convert = new UserInfoSimpleConvert();
        ConverResourceUtils.converList(result, organizations, convert);
        return result;
    }

    @Override
    public UserInfoResponse login(UserInfoDataRequest request) {
        UserInfoResponse result = new UserInfoResponse();
        UsernamePasswordToken token = new UsernamePasswordToken(request.getUsername(), request.getPassword());
        try {
            SecurityUtils.getSubject().login(token);
            result.setSessionId("" + SecurityUtils.getSubject().getSession().getId());
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            result.setCode(501);
            result.setMsg("该账号不存在");
        } catch (LockedAccountException e) {
            e.printStackTrace();
            result.setCode(502);
            result.setMsg("该账号被禁用");
        } catch (AuthenticationException e) {
            e.printStackTrace();
            result.setCode(503);
            result.setMsg("密码错误");
        } catch (Exception e) {
            result.setCode(501);
            result.setMsg("账号或者密码错误");
        }

        return result;
    }

    @Override
    public MenuList menu() {
        MenuList result = new MenuList();
        ShiroUser user = UserUtil.getCurrentShiroUser();
        if (user == null) {
            result.setCode(401);
            result.setMsg("没有权限");
            return result;
        }
        Set<String> permissions = null;
        Object data = SecurityUtils.getSubject().getSession().getAttribute("permissions");
        if (data instanceof Set) {
            permissions = (Set<String>) data;
        }

        /**
         * 如果获取不了用户权限，重新获取
         */
        if (permissions == null) {
            permissions = new HashSet<>();
            UserInfo tenantUser = dataDao.findById(user.getId());
            if (tenantUser != null) {
                Set<UserRole> roles = tenantUser.getRoles();
                if (roles != null) {
                    for (UserRole role : roles) {
                        List<String> permissionList = role.getAuthorities();
                        if (permissionList != null & permissionList.size() > 0) {
                            permissions.addAll(permissionList);
                        }
                    }
                }
            }
        }

        /**
         * 获取系统菜单
         */
        List<Filter> filers = new ArrayList<>();
        filers.add(Filter.eq("levelInfo", 2));
        filers.add(Filter.eq("menuType", 0));

        List<Order> orders = new ArrayList<>();
        orders.add(Order.asc("sortNum"));
        List<Menu> menus = menuDao.list(0, 1000, filers, orders);
        if (menus != null && menus.size() > 0) {
            for (Menu menu : menus) {
                MenuSimple simple = new MenuSimpleConvert().conver(menu);
                if (permissions.contains(simple.getPermission())) {
                    result.getList().add(simple);
                }
                //处理子节点
                handleChildren(permissions, menu, simple);
            }
        }
        return result;
    }
    private void handleChildren(Set<String> permissions, Menu menu, MenuSimple simple) {
        if (menu.getChildrens() != null && menu.getChildrens().size() > 0) {
            List<Menu> children = menu.getChildrens();
            for (Menu child : children) {
                MenuSimple childSimple = new MenuSimpleConvert().conver(child);
                if (permissions.contains(childSimple.getPermission())) {
                    if (simple.getChildren()==null){
                        simple.setChildren(new ArrayList<>());
                    }
                    simple.getChildren().add(childSimple);
                }
                if (child.getChildrens() != null && child.getChildrens().size() > 0) {
                    handleChildren(permissions, child, childSimple);
                }
            }
        }
    }
    @Override
    public UserInfoPage search(UserInfoSearchRequest request) {
        UserInfoPage result = new UserInfoPage();
        Pageable pageable = new PageableConver().conver(request);
        pageable.getFilters().addAll(FilterUtils.getFilters(request));
        if ("asc".equals(request.getSortMethod())) {
            pageable.getOrders().add(Order.asc("" + request.getSortField()));
        } else if ("desc".equals(request.getSortMethod())) {
            pageable.getOrders().add(Order.desc("" + request.getSortField()));
        } else {
            pageable.getOrders().add(Order.desc("id"));
        }
        Page<UserInfo> page = dataDao.page(pageable);
        UserInfoSimpleConvert convert = new UserInfoSimpleConvert();
        ConverResourceUtils.converPage(result, page, convert);
        return result;
    }

    @Override
    public UserInfoPage changePassword(UpdatePasswordRequest request) {
        UserInfoPage result = new UserInfoPage();
        if (request.getId() == null) {
            result.setCode(501);
            result.setMsg("用户id为空");
            return result;
        }
        UserInfo info = dataDao.findById(request.getId());
        if (info == null) {
            result.setCode(502);
            result.setMsg("用户为空");
            return result;
        }
        ResponseObject res = dataDao.updatePassword(request);
        if (res.getCode() != 0) {
            result.setCode(res.getCode());
            result.setMsg(res.getMsg());
            return result;
        }
        return result;
    }

    @Override
    public UserInfoPage restPassword(ResetPasswordRequest request) {
        UserInfoPage result = new UserInfoPage();
        if (request.getId() == null) {
            result.setCode(501);
            result.setMsg("用户id为空");
            return result;
        }
        UserInfo info = dataDao.findById(request.getId());
        if (info == null) {
            result.setCode(502);
            result.setMsg("用户为空");
            return result;
        }
        ResponseObject res = dataDao.resetPassword(request);
        if (res.getCode() != 0) {
            result.setCode(res.getCode());
            result.setMsg(res.getMsg());
            return result;
        }
        return result;
    }
}
